
int main()
{
    unsigned char a[0x10];
    unsigned long r6, r12, r13, r14;

    asm("xld.w %r4,0x3000");
    asm("ld.w %sp,%r4");
    // CEFUNC(#CE pin function selection): #CE7/8..#CE17/18
    *(volatile unsigned char *)0x00048131 = 0x04;
    // P24(CLE)、P25(ALE): Output
    *(volatile unsigned char *)0x000402da |= 0x30;
    // P26(RY/#BY): High
    *(volatile unsigned char *)0x000402d9 |= 1<<6;
    // P51(#CE15+#CE16): Low
    *(volatile unsigned char *)0x00300022 &= ~(1<<1);
    // P24(CLE): High
    *(volatile unsigned char *)0x000402d9 |= 1<<4;
    // nand flash Read ID Commands
    *(volatile unsigned char *)0x04000000 = 0x90;
    // P24(CLE): Low
    *(volatile unsigned char *)0x000402d9 &= ~(1<<4);
    // P25(ALE): High
    *(volatile unsigned char *)0x000402d9 |= 1<<5;
    // nand flash Address 1cycle
    (*(volatile unsigned char *)0x04000000) = 0x00;
    // P25(ALE): Low
    *(volatile unsigned char *)0x000402d9 &= ~(1<<5);
    asm("nop");
    // Maker Code (ref: 0xEC)
    a[0x0c] = *(volatile unsigned char *)0x04000000;
    // Device Code (ref: 0xDA)
    a[0x0d] = *(volatile unsigned char *)0x04000000;
    // from nand 0x400 read 0x1400 bytes to RAM 0x200
    for (r13=0x200,r12=0x2,r14=0; r14<10; r13+=0x200,r12++,r14++) {
        // P24(CLE): High
        *(volatile unsigned char *)0x000402d9 |= 1<<4;
        // nand flash Read Operation
        *(volatile unsigned char *)0x04000000 = 0;
        // P24(CLE): Low
        *(volatile unsigned char *)0x000402d9 &= ~(1<<4);
        // P25(ALE): High
        *(volatile unsigned char *)0x000402d9 |= 1<<5;
        if (a[0x0d] > 0xbf) {
            *(volatile unsigned char *)0x04000000 = 0;
            *(volatile unsigned char *)0x04000000 = (r12&3)<<1;
            *(volatile unsigned char *)0x04000000 = r12>>2;
            *(volatile unsigned char *)0x04000000 = 0;
            *(volatile unsigned char *)0x04000000 = 0;
            // P25(ALE): Low
            *(volatile unsigned char *)0x000402d9 &= ~(1<<5);
            // P24(CLE): High
            *(volatile unsigned char *)0x000402d9 |= 1<<4;
            *(volatile unsigned char *)0x04000000 = 0x30;
            // P24(CLE): Low
            *(volatile unsigned char *)0x000402d9 &= ~(1<<4);
        } else {
            *(volatile unsigned char *)0x04000000 = 0;
            *(volatile unsigned char *)0x04000000 = r12;
            *(volatile unsigned char *)0x04000000 = 0;
            *(volatile unsigned char *)0x04000000 = 0;
            // P25(ALE): Low
            *(volatile unsigned char *)0x000402d9 &= ~(1<<5);
        }
        // Busy(RY/#BY): while (P26 == Low) {}
        while((*(volatile unsigned char *)0x000402d9 & 0x40) == 0x00) {
        }
        for (r6=0; r6<0x200; r6++) {
            *(volatile unsigned char *)(r13+r6) = *(volatile unsigned char *)0x04000000;
        }
    }
    // P51(#CE15+#CE16): High
    *(volatile unsigned char *)0x00300022 |= 1<<1;
    
    // typedef void *func();
    // ((func *)0x200)();
    ((void(*)())0x200)();
}
